package services.impl;

import com.jfinal.aop.Inject;

import beans.UserBean;
import constants.CommonConstant;
import dto.Dto;
import mapper.UserMapper;
import models.Profile;
import models.TokenModel;
import models.User;
import services.IUserService;
import utils.RedisUtil;

public class UserServiceImpl implements IUserService{
	@Inject
	TokenServiceImpl tokenService;
	@Inject
	UserMapper userMapper;
	
	private RedisService redisService = new RedisService();

	@Override
	public Dto login(String userName, String password) {
		Dto dto = new Dto();
		User user = userMapper.getUserByName(userName);
		if(user==null||!user.getPassword().equals(password)){
			// show error message
			dto.setErrMsg("Authorization failed.");
			return Dto.getFinalDto(dto);
		}
		// create token; save into redis
		String userId = user.getId();
		String token = tokenService.createToken(userId);
		RedisUtil.addCache(redisService, RedisUtil.AUTHERIZE_CACHE_EX, CommonConstant.AUTH_CACHE_KEY_PRE+userId, token);
		TokenModel tokenModel = new TokenModel();
		tokenModel.setToken(token);
		dto.setData(tokenModel);
		return Dto.getFinalDto(dto);
	}

	@Override
	public Dto signUp(UserBean bean) {
		Dto dto = new Dto();
		//bean check
		
//		new User().set("id",null).set("password",user.getPassword()).set("name", user.getName()).save();
		User user = userMapper.getUserByName(bean.getUserName());
		if(user!=null){
			dto.setErrMsg("This user name has been used, please use another one.");
			return dto;
		}
		// create user & profile
		user = getUserDataFromBean(bean);
		Profile profile = getProfileDataFromBean(bean);
		if(userMapper.userSignUp(user,profile)){
			dto.setData(profile);
		}else{
			dto.setErrMsg("Unexpected error while creating user.");
		}
		return Dto.getFinalDto(dto);
	}
	
	private User getUserDataFromBean(UserBean bean){
		User user = new User();
		user.setName(bean.getUserName());
		user.setPassword(bean.getPassword());
		user.setPhoneNumber(bean.getPhoneNumber());
		return user;
	}
	
	private Profile getProfileDataFromBean(UserBean bean){
		Profile profile = new Profile();
		profile.setNickName(bean.getNickName());
		profile.setPhoneNumber(bean.getPhoneNumber());
		profile.setBirthDate(bean.getBirthDate());
		profile.setEmailAddress(bean.getEmailAddress());
		return profile;
	}
	
	private Profile updateProfileRecordFromBean(Profile profile, UserBean bean){
		if(bean.getNickName()!=null){
			profile.setNickName(bean.getNickName());
		}
		if(bean.getPhoneNumber()!=null){
			profile.setPhoneNumber(bean.getPhoneNumber());
		}
		if(bean.getBirthDate()!=null){
			profile.setBirthDate(bean.getBirthDate());
		}
		if(bean.getEmailAddress()!=null){
			profile.setEmailAddress(bean.getEmailAddress());
		}
		return profile;
	}

	@Override
	public Dto changePassword(UserBean bean) {
		Dto dto = new Dto();
		String userName = bean.getUserName();
		String password = bean.getPassword();
		User user = userMapper.getUserByName(userName);
		if(user==null||!user.getPassword().equals(password)){
			// show error message
			dto.setErrMsg("Authorization failed.");
			return Dto.getFinalDto(dto);
		}
		//update the password to DB
		user.setPassword(bean.getNewPassword());
		if(!userMapper.updateUser(user)){
			//updated failed
			dto.setErrMsg("Change the password failed while updating to DB.");
			return Dto.getFinalDto(dto);
		}
		//clean the redis cache with current authorization
		RedisUtil.clearCacheByKey(redisService, CommonConstant.AUTH_CACHE_KEY_PRE+user.getId());
		return Dto.getFinalDto(dto);
	}

	@Override
	public Dto updateProfile(UserBean bean) {
		Dto dto = new Dto();
		String userId = bean.getUserId();
		//get current profile first
//		Profile profile = userMapper.getProfile(userId);
		Profile profile = userMapper.getProfile(userId);
		if(profile==null){
			dto.setErrMsg("Can not find the current user profile.");
			return Dto.getFinalDto(dto);
		}
		profile = updateProfileRecordFromBean(profile,bean);
		//update the profile to DB
		if(!userMapper.updateProfile(profile)){
			dto.setErrMsg("Update the profile failed while updating to DB.");
			return Dto.getFinalDto(dto);
		}
		dto.setData(profile);
		return Dto.getFinalDto(dto);
	}

	@Override
	public Dto getProfile(UserBean bean) {
		Dto dto = new Dto();
		String userId = bean.getUserId();
		Profile profile = userMapper.getProfile(userId);
		if(profile==null){
			dto.setErrMsg("Get profile error");
			return Dto.getFinalDto(dto);
		}
		dto.setData(profile);
		return Dto.getFinalDto(dto);
	}
}
